上篇介紹了如何透過 materialization 來實作 BigQuery UDF,建立完 materialization 後,本篇來介紹如何在 model 中開發和使用 UDF。
首先要先在 dbt_project.yml 定義 UDF 存放在數據庫(BigQuery) 中哪個 dataset,並告訴 dbt 這個 dataset 會對應到哪個資料夾,還需要定義這個資料夾的 materialization(UDF 底下又會分成 function 和 table_function 兩個資料夾)
models:
udf:
+tags: udf
+database: joshua-1000
+schema: udf
function:
+materialized: function
table_function:
+materialized: table_function
接著就能在 udf/function 資料夾中開發 function model 了!
在開發 UDF model 時,可以分為兩大部分,第一部分是填寫 UDF materialization 的設定(config),第二部分則是 UDF 實際在做的事(例如將字串時間轉為 datetime),以下為參考範例
# udf/function/isotime_to_datetime.sql
# config 必填的參數有 params 和 return_type
{{
config(
params = [
'timestamp_str STRING',
'timezone STRING'
],
return_type='DATETIME'
)
}}
DATETIME(PARSE_TIMESTAMP("%Y-%m-%dT%H:%M:%E*SZ", timestamp_str), timezone)
原本在 dbt 使用 UDF 都只能寫死 UDF 的路徑及名稱,但現在用 dbt model 開發 UDF,就能像其他 model 一樣透過 ref 來引用,可以建立彼此的上下游關係
SELECT
{{ ref(isotime_to_datetime) }}(datetime_str)
FROM
...
在原本用其他 repo 開發 UDF 的其中一個痛點為,在改動 UDF 時需要手動建立一個測試用的 UDF,並且要改原本有使用的 model 中 UDF 的路徑和名稱,來測試這次異動是否正確,但這會花費許多時間且可能會漏改導致測試不完全。
在先前的文章中有提到,我們團隊的測試環境使用是原本的 dataset 名稱後面加 *ci 的後綴,並改寫 get_*custom_schema macro 透過指定 target 來將原本 dataset 名稱加上 _ci(詳細可參考之前文章-超連結)。
因此只要在 PR 時開發或修改 UDF model,就會在 udf_ci 中建立測試的 UDF,而其他 model 有引用這些異動的 UDF model 也會套用測試環境的 UDF,就能減少手動建立測試 UDF 時間,也確保測試環境中每個 model 都有使用到測試 UDF
以上就是 UDF model 開發與使用的方法,下一篇將會統整兩種在 dbt 實作 UDF 的方式(macro & materialization),並比對兩個方法的優劣。